
package instrfetch
import chisel3._
import _root_.util.MemPort
class I_D_Bus extends Bundle{
  val D_Stall_Pass = Input(UInt(32.W))
  val D_NewPC_Pass = Input(UInt(32.W))
  val I_PC = Output(UInt(32.W))
  val I_PC_Pass = Output(UInt(32.W))
  val I_Instr = Output(UInt(32.W))
  val I_Stall_Pass = Output(Bool())
}
class InstrFetchStage(PC_Init : UInt) extends Module{
  val io = IO(new Bundle{
    val instrMemPort = Flipped(new MemPort)
    val D_Bus = new I_D_Bus
  })
  assert(PC_Init.getWidth == 32)
  val PC = RegInit(PC_Init)
  val I_PC = RegInit(PC_Init - 4.U)//由于流水级的原因，第一拍肯定会是nop，必须让下一拍数据从内存中取
  val Instr = RegInit(0.U(32.W))

  val instrValid = io.instrMemPort.data.valid
  val memPort = io.instrMemPort
  val D_Bus = io.D_Bus
  val D_Stall_Pass = D_Bus.D_Stall_Pass
  when(instrValid && !D_Stall_Pass) {
    PC := D_Bus.D_NewPC_Pass
    I_PC := PC
    Instr := memPort.data.bits
  }
  D_Bus.I_PC := I_PC
  D_Bus.I_PC_Pass := PC
  D_Bus.I_Instr := Instr
  D_Bus.I_Stall_Pass := !instrValid
}
